package OdooRpc

import (
	"bytes"
	"errors"
	"github.com/divan/gorilla-xmlrpc/xml"
	"github.com/go-ini/ini" //ini配置库
	"log"
	"net/http"
)

//一些odoo连接时用到的变量
var (
	PushToOdoo                   bool   //指示是否推送到odoo数据库，如果选择false下面的函数将不会通过xmlrpc发送
	XML_RPC_METHOD               string //如excute
	XML_RPC_URL                  string //如http://127.0.0.1:8069/xmlrpc/object
	DB_NAME                      string //数据库名字如11
	UID                          int    //登录的用户名id 1 代表admin
	PWD                          string //用户登录密码如1989112
	ODOO_PostParaStruct_MODEL    string //如nmbw800.mymodel
	PostParaStruct_Method        string //推送结构体时接收的方法如addIntance
	Odoo_PostDayRecord_Model     string //推送日记录的模型
	Odoo_PostDayRecord_Method    string //推送日记录的方法
	Odoo_PostDetailRecord_Model  string //推送日记录的模型
	Odoo_PostDetailRecord_Method string //推送日记录的方法
)

func init() {
	log.SetFlags(log.Lshortfile | log.LstdFlags)
	cfg, _ := ini.Load("./conf.ini")

	//从ini配置文件获取
	PushToOdoo, _ = cfg.Section("service").Key("PushToOdoo").Bool()
	XML_RPC_METHOD = cfg.Section("odooLink").Key("xmlRpcMethod").String()
	XML_RPC_URL = cfg.Section("odooLink").Key("xmlRpcUrl").String()
	DB_NAME = cfg.Section("odooLink").Key("dbName").String() //数据库名字
	UID = cfg.Section("odooLink").Key("uid").MustInt()       //登录的用户名id 1 代表admin
	PWD = cfg.Section("odooLink").Key("password").String()
	ODOO_PostParaStruct_MODEL = cfg.Section("paraStruct").Key("odooModal").String()
	PostParaStruct_Method = cfg.Section("paraStruct").Key("odooMethod").String()          //推送结构体时接收的方法
	Odoo_PostDayRecord_Model = cfg.Section("dayRecord").Key("odooModal").String()         //推送日记录的模型
	Odoo_PostDayRecord_Method = cfg.Section("dayRecord").Key("odooMethod").String()       //推送日记录的方法
	Odoo_PostDetailRecord_Model = cfg.Section("detailRecord").Key("odooModal").String()   //推送日记录的模型
	Odoo_PostDetailRecord_Method = cfg.Section("detailRecord").Key("odooMethod").String() //推送日记录的方法

}

//从ini配置文件中获取要用到的odoo连接参数

type Send struct {
	Dbname string //pg数据库
	Uid    int    //用户id
	Pwd    string //用户密码
	Model  string //调用的模块
	Method string //模块方法
	Args   string //参数，可以是数组,我们发送的是json化的结构体
}

//xmlRpc的post组包
func XmlRpcCall(model string, method string, args string) (reply struct{ Message string }, err error) {
	if PushToOdoo { //如果配置是key推送到odoo的就推送
		send := Send{DB_NAME, UID, PWD, model, method, args}
		buf, _ := xml.EncodeClientRequest(XML_RPC_METHOD, &send)

		resp, err1 := http.Post(XML_RPC_URL, "text/xml", bytes.NewBuffer(buf))
		if err1 != nil {
			return struct{ Message string }{}, err1
		}
		defer resp.Body.Close()

		err = xml.DecodeClientResponse(resp.Body, &reply)
		return reply, err
	} else { //如果配置成是不可以推送到odoo，就返回一个错误
		myerr := errors.New("配置文件中没有启用odoo推送，不进行发送到odoo的数据库中。")
		return struct{ Message string }{}, myerr
	}
}

//错误处理
func handleerr(err error) {
	if err.Error() == "配置文件中没有启用odoo推送，不进行发送到odoo的数据库中。" {
		log.Println(err.Error())
		return
	}
	log.Println("错误可能是odoo的admin密码修改了，或者odoo没有启动，或者odoo中设置了权限（就是postNm800Para.go里面的常量要更改了）")
	log.Fatal(err)
}

//推送parastruct到odoo
func PostParaStruct(jsonstruct string) {
	reply, err := XmlRpcCall(ODOO_PostParaStruct_MODEL, PostParaStruct_Method, jsonstruct)

	if err != nil {
		handleerr(err)
	} else {
		log.Printf("添加参数结构体到odoo数据库，id：%s", reply)
	}

}

//推送日下料记录到odoo
func PostDayRecord(jsonRecordList string) {
	reply, err := XmlRpcCall(Odoo_PostDayRecord_Model, Odoo_PostDayRecord_Method, jsonRecordList)

	if err != nil {
		handleerr(err)
	} else {
		log.Printf("添加日记录列表结构体到odoo数据库：%s", reply)
	}

}

//推送详细下料记录到odoo
func PostDetailRecord(jsonRecordList string) {
	reply, err := XmlRpcCall(Odoo_PostDetailRecord_Model, Odoo_PostDetailRecord_Method, jsonRecordList)

	if err != nil {
		handleerr(err)

	} else {
		log.Printf("添加详细记录列表结构体到odoo数据库：%s", reply)
	}

}

// func main() {
// 	reply, err := XmlRpcCall("test", "1")
// 	if err != nil {
// 		log.Fatal(err)
// 	}

// 	log.Printf("Response: %s\n", reply)
// }
